/**
*  \file    scast.h
*
*  \brief   cast routines with data type limit saturation
*
*  \author  Francesco D'Aprea <francesco.daprea@linde-mh.de>
*
*
*/

#ifndef SCAST_H_INCLUDED
#define SCAST_H_INCLUDED

/*================================================[ public includes  ]================================================*/
#include "../cfg/prj.h"

/*================================================[ public defines   ]================================================*/

#define SATURATED_CAST_MAX( T_PASS, T_RET ) \
   if ( ((T_PASS)T_RET##_MAX) > val ) \
   { \
      return ((T_RET) val); \
   } \
   else \
   { \
      return T_RET##_MAX; \
   }

#define SATURATED_CAST_MIN_MAX( T_PASS, T_RET ) \
   if ( ((T_PASS)T_RET##_MAX) <= val ) \
   { \
      return T_RET##_MAX; \
   } \
   else if ( ((T_PASS)T_RET##_MIN) >= val ) \
   { \
      return T_RET##_MIN; \
   } \
   else \
   { \
      return ((T_RET) val); \
   }

#define SATURATED_CAST_MIN( T_PASS, T_RET ) \
   if ( ((T_PASS)T_RET##_MIN) >= val ) \
   { \
      return T_RET##_MIN; \
   } \
   else \
   { \
      return ((T_RET) val); \
   }

/*================================================[ public datatypes ]================================================*/

/*================================================[ public variables ]================================================*/

/*================================================[ public functions ]================================================*/

/* U8 to S8 */
STATIC_INLINE S8 saturated_cast_U8_S8( U8 val )
{
   SATURATED_CAST_MAX( U8, S8 )
}


/* U16 to U8, S8, S16 */
STATIC_INLINE U8 saturated_cast_U16_U8( U16 val )
{
   SATURATED_CAST_MAX( U16, U8 )
}

STATIC_INLINE S8 saturated_cast_U16_S8( U16 val )
{
   SATURATED_CAST_MAX( U16, S8 )
}

STATIC_INLINE S16 saturated_cast_U16_S16( U16 val )
{
   SATURATED_CAST_MAX( U16, S16 )
}


/* U32 to U8, S8, U16, S16, S32 */
STATIC_INLINE U8 saturated_cast_U32_U8( U32 val )
{
   SATURATED_CAST_MAX( U32, U8 )
}

STATIC_INLINE S8 saturated_cast_U32_S8( U32 val )
{
   SATURATED_CAST_MAX( U32, S8 )
}

STATIC_INLINE U16 saturated_cast_U32_U16( U32 val )
{
   SATURATED_CAST_MAX( U32, U16 )
}

STATIC_INLINE S16 saturated_cast_U32_S16( U32 val )
{
   SATURATED_CAST_MAX( U32, S16 )
}

STATIC_INLINE S32 saturated_cast_U32_S32( U32 val )
{
   SATURATED_CAST_MAX( U32, S32 )
}


/* S8 to U8, U16, U32 */
STATIC_INLINE U8 saturated_cast_S8_U8( S8 val )
{
   SATURATED_CAST_MIN( S8, U8 )
}

STATIC_INLINE U16 saturated_cast_S8_U16( S8 val )
{
   SATURATED_CAST_MIN( S8, U16 )
}

STATIC_INLINE U32 saturated_cast_S8_U32( S8 val )
{
   SATURATED_CAST_MIN( S8, U32 )
}


/* S16 to S8, U8, U16, U32 */
STATIC_INLINE S8 saturated_cast_S16_S8( S16 val )
{
   SATURATED_CAST_MIN_MAX( S16, S8 )
}

STATIC_INLINE U8 saturated_cast_S16_U8( S16 val )
{
   SATURATED_CAST_MIN_MAX( S16, U8 )
}

STATIC_INLINE U16 saturated_cast_S16_U16( S16 val )
{
   SATURATED_CAST_MIN( S16, U16 )
}

STATIC_INLINE U32 saturated_cast_S16_U32( S16 val )
{
   SATURATED_CAST_MIN( S16, U32 )
}


/* S32 to S8, U8, S16, U16, U32 */
STATIC_INLINE S8 saturated_cast_S32_S8( S32 val )
{
   SATURATED_CAST_MIN_MAX( S32, S8 )
}

STATIC_INLINE U8 saturated_cast_S32_U8( S32 val )
{
   SATURATED_CAST_MIN_MAX( S32, U8 )
}

STATIC_INLINE S16 saturated_cast_S32_S16( S32 val )
{
   SATURATED_CAST_MIN_MAX( S32, S16 )
}

STATIC_INLINE U16 saturated_cast_S32_U16( S32 val )
{
   SATURATED_CAST_MIN_MAX( S32, U16 )
}

STATIC_INLINE U32 saturated_cast_S32_U32( S32 val )
{
   SATURATED_CAST_MIN( S32, U32 )
}

/*====================================================================================================================*/

#endif

/***********************************************************************************************************************
*                             Copyright 2010 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/
